BARYCENTRIC_INTERP

Overview

The BARYCENTRIC_INTERP function performs polynomial interpolation using the barycentric formulation of Lagrange interpolation. Given a set of data points, it constructs a polynomial that passes exactly through all points, then evaluates that polynomial at specified locations. This technique is widely used in numerical analysis for curve fitting, data approximation, and function reconstruction.

Barycentric interpolation is a reformulation of Lagrange polynomial interpolation that offers improved numerical stability and computational efficiency. The method expresses the interpolating polynomial using pre-computed barycentric weights w_j, defined as:

w_j = \frac{1}{\prod_{m \neq j}(x_j - x_m)}

The interpolated value at any point x is then computed using the second (true) barycentric form:

L(x) = \frac{\sum_{j=0}^{k} \frac{w_j}{x - x_j} y_j}{\sum_{j=0}^{k} \frac{w_j}{x - x_j}}

This formulation avoids explicit computation of the polynomial coefficients, which enhances numerical stability. The algorithm is numerically stable because potential cancellation errors in the terms (x - x_j) appear in both numerator and denominator, effectively canceling out.

This implementation uses SciPy’s barycentric_interpolate function from the scipy.interpolate module. The source code is available in the SciPy GitHub repository.

Important consideration: While barycentric interpolation is numerically stable, polynomial interpolation itself can be ill-conditioned for certain node distributions due to Runge’s phenomenon, which causes large oscillations at the edges of the interval. For best results with many interpolation points, consider using Chebyshev nodes (points at \cos(i\pi/n)) rather than equally spaced points.

This example function is provided as-is without any representation of accuracy.

Excel Usage

=BARYCENTRIC_INTERP(xi, yi, x)
  • xi (list[list], required): The x-coordinates of the data points
  • yi (list[list], required): The y-coordinates of the data points
  • x (list[list], required): The x-coordinates at which to evaluate

Returns (list[list]): A 2D list (column vector) of interpolated values, or an error message (str) if invalid.

Examples

Example 1: Demo case 1

Inputs:

xi yi x
0 0 0.5
1 1

Excel formula:

=BARYCENTRIC_INTERP({0;1}, {0;1}, {0.5})

Expected output:

Result
0.5

Example 2: Demo case 2

Inputs:

xi yi x
0 0 1.5
1 1
2 4

Excel formula:

=BARYCENTRIC_INTERP({0;1;2}, {0;1;4}, {1.5})

Expected output:

Result
2.25

Example 3: Demo case 3

Inputs:

xi yi x
1 1 1.5
2 4 2.5
3 9

Excel formula:

=BARYCENTRIC_INTERP({1;2;3}, {1;4;9}, {1.5;2.5})

Expected output:

Result
2.25
6.25

Example 4: Demo case 4

Inputs:

xi yi x
0 1 1
1 2
2 5
3 10

Excel formula:

=BARYCENTRIC_INTERP({0;1;2;3}, {1;2;5;10}, {1})

Expected output:

Result
2

Python Code

import math
from scipy.interpolate import barycentric_interpolate as scipy_barycentric_interpolate

def barycentric_interp(xi, yi, x):
    """
    Interpolating polynomial for a set of points using barycentric interpolation.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.barycentric_interpolate.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        xi (list[list]): The x-coordinates of the data points
        yi (list[list]): The y-coordinates of the data points
        x (list[list]): The x-coordinates at which to evaluate

    Returns:
        list[list]: A 2D list (column vector) of interpolated values, or an error message (str) if invalid.
    """
    def to2d(val):
        """Convert scalar or 2D list to 2D list format."""
        return [[val]] if not isinstance(val, list) else val

    def flatten(arr):
        """Flatten a 2D list to a 1D list."""
        return [item for sublist in arr for item in sublist]

    def validate_numeric_list(arr, name):
        """Validate that a 2D list contains only finite numeric values."""
        if not isinstance(arr, list):
            return f"Invalid input: {name} must be a list."
        if not arr:
            return f"Invalid input: {name} cannot be empty."
        for i, row in enumerate(arr):
            if not isinstance(row, list):
                return f"Invalid input: {name} must be a 2D list."
            for j, val in enumerate(row):
                if not isinstance(val, (int, float)):
                    return f"Invalid input: {name}[{i}][{j}] must be numeric."
                if math.isnan(val) or math.isinf(val):
                    return f"Invalid input: {name}[{i}][{j}] must be finite."
        return None

    # Normalize inputs to 2D lists
    xi = to2d(xi)
    yi = to2d(yi)
    x = to2d(x)

    # Validate inputs
    error = validate_numeric_list(xi, "xi")
    if error:
        return error
    error = validate_numeric_list(yi, "yi")
    if error:
        return error
    error = validate_numeric_list(x, "x")
    if error:
        return error

    # Flatten to 1D arrays
    xi_flat = flatten(xi)
    yi_flat = flatten(yi)
    x_flat = flatten(x)

    # Check that xi and yi have the same length
    if len(xi_flat) != len(yi_flat):
        return "Invalid input: xi and yi must have the same length."

    # Check minimum points requirement
    if len(xi_flat) < 1:
        return "Invalid input: at least one data point is required."

    # Check for duplicate xi values
    if len(xi_flat) != len(set(xi_flat)):
        return "Invalid input: xi values must be unique."

    try:
        # Call scipy.interpolate.barycentric_interpolate
        result = scipy_barycentric_interpolate(xi_flat, yi_flat, x_flat)

        # Convert result to list and validate
        if hasattr(result, '__iter__'):
            result_list = list(result)
        else:
            result_list = [result]

        # Validate all results are finite
        for i, val in enumerate(result_list):
            if not isinstance(val, (int, float)):
                return f"scipy.interpolate.barycentric_interpolate error: non-numeric result at index {i}."
            if math.isnan(val) or math.isinf(val):
                return f"scipy.interpolate.barycentric_interpolate error: non-finite result at index {i}."

        # Return as 2D column vector
        return [[float(val)] for val in result_list]

    except Exception as exc:
        return f"scipy.interpolate.barycentric_interpolate error: {exc}"

Online Calculator